<?php
declare (strict_types=1);

namespace app\madmin\service;

use app\madmin\model\Commodity;
use app\madmin\model\Coupon;
use app\madmin\model\Merchant as admin;
use app\madmin\model\MerchantApply;
use app\madmin\model\MerchantCash;
use app\madmin\model\ShopAdmin;
use app\madmin\model\ShopRole;
use app\madmin\model\ShopRoleRule;
use app\madmin\model\ShopRule;
use app\madmin\model\User;
use app\utils\RedisUtil;
use app\utils\TrimData;
use think\db\exception\PDOException;
use think\helper\Str;
use think\model\Relation;

class MerchantService
{

    private $redis;

    private $user;

    public function __construct()
    {
        $this->redis = new RedisUtil();
        global $user;
        $this->user = $user;
    }

    public function getMerchantAndCommodityByIds($ids)
    {
        $list = admin::with(['commodity' => function (Relation $query) {
            $query->field('id,merchant_id,name,master,sell_price')
                ->hidden(['merchant_id'])
                ->withLimit(3);
        }])
            ->field("id,name,logo")
            ->where(['id' => $ids])
            ->withCount(['commodity'])
            ->select();
        return [HTTP_SUCCESS, $list];
    }

    /**
     * 查询列表
     * @param int $page
     * @param int $size
     * @param array $data
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function findAll(array $data, int $page = 1, int $size = 10)
    {
        $admin = admin::field('id,mall_id,username,password,user_id,name,logo,mobile,company,district,address,longitude,latitude,remark,content,business_license,indate,type,audit_type,status,create_time,update_time');
        $admin = TrimData::searchDataTrim($admin, $data, ['name', 'mobile', 'company', 'begin_date', 'end_date']);

        $list = $admin->where($data)
            ->where('is_self', 0)
            ->paginate(['page' => $page, 'list_rows' => $size])->toArray();
        return [HTTP_SUCCESS, $list];
    }

    /**
     * 保存数据
     * @param array $data
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function save(array $data)
    {
        if (isset($data['apply_id'], $data['update_time'])) {
            $apply = MerchantApply::where(['id' => $data['apply_id'], 'update_time' => $data['update_time'], 'status' => 0])
                ->update(['status' => 1]);
            if (empty($apply))
                throw new \PDOException('保存失败', HTTP_NOTACCEPT);
            unset($data['update_time']);
            $merchantOld = admin::onlyTrashed()->find(['user_id' => $data['user_id']]);
            if ($merchantOld) {
                $merchantOld->restore();
                User::where(['id' => $data['user_id']])->update(['merchant_id' => $merchantOld->id]);
                return [HTTP_CREATED, $merchantOld];
            }
        }

        //创建商户
        $data['is_self'] = 0;
        try {
            $model = admin::create($data);
        } catch (PDOException $e) {
            if (strpos($e->getMessage(), "Index_username") !== false) {
                throw new \PDOException('账号已存在', HTTP_INVALID);
            }

            if (strpos($e->getMessage(), "Index_mobile") !== false) {
                throw new \PDOException('手机号已存在', HTTP_INVALID);
            }
        }

        //添加后台账号
        $usernameAndPassword = $this->insertToDbAndFile($model);

        admin::update($usernameAndPassword, ['id' => $model->id]);

        User::where(['id' => $data['user_id']])->update(['merchant_id' => $model->id]);
        MerchantCash::create(['merchant_id' => $model->id]);
        return [HTTP_CREATED, ["model" => $model, "secret" => $usernameAndPassword]];
    }

    private function insertToDbAndFile($model)
    {

        //创建角色
        $roleData = array(
            "mall_id" => $this->user->mall_id,
            "merchant_id" => $model->id,
            "name" => "超级管理员",
            "remark" => "拥有所有权限",
            "department_id" => 1,
            "is_root" => 1
        );
        $role = ShopRole::create($roleData);

        //创建关联
        $shopRule = new ShopRule();
        $ruleList = $shopRule->column("id");
        foreach ($ruleList as $v) {
            ShopRoleRule::create(['role_id' => $role->id, 'rule_id' => $v]);
        }

        //创建登录账号
        $username = Str::random(8);
        $password = Str::random(12);
        $adminData = array(
            "mall_id" => $this->user->mall_id,
            "merchant_id" => $model->id,
            "username" => $username,
            "password" => hash("sha256", $password),
            "mobile" => $model->mobile,
            "role_id" => $role->id,
            "name" => "商户管理员",
            "login_ip" => "127.0.0.1",
            "status" => 1,
            "is_root" => 1
        );
        ShopAdmin::create($adminData);
        return ['username' => $username, 'password' => $password];
    }


    /**
     * 读取一条数据
     * @param int $id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function read(int $id)
    {
        $model = admin::with(['user', 'cash'])->find($id);
        return [HTTP_SUCCESS, $model];
    }


    /**
     * 更新数据
     * @param int $id
     * @param array $data
     * @return array
     */
    public function update(int $id, array $data)
    {
        $update_time = $data['update_time'];
        unset($data['update_time']);
        unset($data['user_name']);

        try {
            $admin = admin::update($data, ['id' => $id, 'update_time' => $update_time]);
        } catch (PDOException $e) {
            if (strpos($e->getMessage(), "Index_mobile") !== false) {
                throw new \PDOException('手机号已存在', HTTP_INVALID);
            }
        }

        if (isset($data['status']) && empty($data['status'])) {
            $this->shelf($id);
        }
        return [HTTP_CREATED, $admin];
    }

    /**
     * @param $id
     * @return int
     */
    public function delete($id)
    {
        $model = admin::find($id);
        User::where(['id' => $model->user_id])->update(['merchant_id' => null]);
        $this->shelf($id);
        admin::destroy($id);
        return HTTP_NOCONTEND;
    }

    private function shelf($merchantId)
    {
        $ids = Commodity::where(['merchant_id' => $merchantId, 'status' => 1])->column('id');
        Commodity::where('id', 'in', $ids)->update(['status' => 0]);
        foreach ($ids as $id) {
            $this->redis->delete(checkRedisKey("COMMODITY:" . $id));
            $this->deleteInventory("COMMODITY:" . $id . ":*SELL");
        }
        Coupon::where(['merchant_id' => $merchantId, 'status' => 1])->update(['status' => 0]);
        return true;
    }

    private function deleteInventory(string $pattern)
    {
        $keys = $this->redis->keys(checkRedisKey($pattern));
        $this->redis->del($keys);
    }

}
